﻿using System;
using System.Reflection;

namespace Net.Adapter
{
    public class RpcFuncPtr<R> : RpcMethodPtr
    {
        public Func<R> ptr;
        public override Type GetActionType => typeof(Func<R>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<R>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr();
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<R>();
    }

    public class RpcFuncPtr<T, T1> : RpcMethodPtr
    {
        public Func<T, T1> ptr;
        public override Type GetActionType => typeof(Func<T, T1>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1>();
    }

    public class RpcFuncPtr<T, T1, T2> : RpcMethodPtr
    {
        public Func<T, T1, T2> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2>();
    }

    public class RpcFuncPtr<T, T1, T2, T3> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5, T6> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5, T6> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5, T6>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5, T6>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4], (T5)pars[5]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5, T6>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5, T6, T7> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5, T6, T7>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5, T6, T7>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4], (T5)pars[5], (T6)pars[6]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5, T6, T7, T8> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5, T6, T7, T8>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5, T6, T7, T8>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4], (T5)pars[5], (T6)pars[6], (T7)pars[7]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8, T9> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4], (T5)pars[5], (T6)pars[6], (T7)pars[7], (T8)pars[8]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8, T9>();
    }

    public class RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : RpcMethodPtr
    {
        public Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ptr;
        public override Type GetActionType => typeof(Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>);
        public override void SetPtr(Delegate ptr)
        {
            this.ptr = ptr as Func<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>;
        }
        public override void Invoke(object target, object[] pars)
        {
            ptr((T)pars[0], (T1)pars[1], (T2)pars[2], (T3)pars[3], (T4)pars[4], (T5)pars[5], (T6)pars[6], (T7)pars[7], (T8)pars[8], (T9)pars[9]);
        }
        public override RpcMethodPtr CreateMethodPtr() => new RpcFuncPtr<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>();
    }
}
